<?php
class Silk_Object extends Silk_Model
{

    protected $_site = null;
    protected $_user = null;
    protected $_type = null;
    protected $_parent = null;

    protected $_translations = null;
    protected $_children = null;
    protected $_term_taxonomies = null;

    protected $_metas = null;
    protected $_new_metas = null;
    protected $_metas_updated = false;

    protected $_data = array(
        'object_id' => null,
        'status' => null,
        'slug' => null,
        'name' => null,
        'content' => null,
        'mimetype' => null,
        'revision' => null,
        'site_id' => null,
        'user_id' => null,
        'type_id' => null,
        'parent_id' => null,
        'route' => null
    );

    public function __set($pAtt, $pVal){
	switch ($pAtt){
	    case 'meta':
		$this->setMetaValues($pVal);
		break;
	    default:
		parent::__set($pAtt, $pVal);
	}
    }

    public function save($pValidate=true){

	if (!$this->slug)
	    $this->slug = to_url_friendly($this->name);

// 	$this->_data['content'] = stripslashes($this->_data['content']);

	parent::save($pValidate);

	if ($this->_metas_updated){
	    $metas = $this->gateway->getMetaCollection($this, $this->_metas);

	    foreach ($metas as $meta)
		$meta->save();

	    if ($this->_new_metas !== null){

		$new_metas = $this->gateway->getMetaCollection($this, $this->_new_metas);

		foreach ($new_metas as $meta){
		    $meta->object_id = $this->object_id;
		    $meta->site_id = $this->site_id;
		    $meta->save();
		}
	    }

	    $this->_new_metas = null;
	    $this->_metas = null;
	    $this->_metas_updated = false;
	}

    }

    public function getResourceName(){
	if ($this->object_id)
	    return "object.{$this->object_id}";
	else
	    return "type.{$this->type_id}";

    }

    public function getModuleType(){
	return $this->gateway->getModuleType($this);
    }

//     public function setMetas($pMeta){
// 	$this->_metas = $this->gateway->updateMetas($this, $pMeta);
// 	$this->_metas_updated = true;
//     }

    public function setMetaValue($pAtt, $pVal) {
	if ($this->_metas === null){
	    $this->getMetas();
	}

	$exists = false;

	foreach ($this->_metas as $meta){
	    if (($meta->name == $pAtt)){
		$exists = true;

		if ($meta->value != $pVal){
		    logdebug("Updating meta $pAtt = $pVal");
		    $meta->value = $pVal;
		    $this->_metas_updated = true;
		}

		break;
	    }
	}

	if (!$exists){
	    if ($this->_new_metas === null)
		$this->_new_metas = array();

	    logdebug("Adding meta $pAtt = $pVal");

	    $this->_new_metas[] = array(
		'name' => $pAtt,
		'value' => $pVal
	    );
	    $this->_metas_updated = true;
	}

    }

    public function setMetaValues(array $pMetaValues){

	foreach ($pMetaValues as $key => $val)
	    $this->setMetaValue($key, $val);

	return true;
    }


    public function getMetaValue($pName){
	$metas = $this->getMetas();

	foreach ($metas as $meta)
	    if ($meta->name == $pName) return stripslashes($meta->value);

	if ($this->_new_metas !== null){
	    foreach ($this->_new_metas as $meta)
		if ($meta['name'] == $pName) return stripslashes($meta['value']);
	}

	return null;
    }

    public function hasPermission($pPrivilege, $pUser=null){

	logdebug("Object.hasPermission: Checking for $pPrivilege on object {$this->object_id}");
	return $this->gateway->hasPermission($this, $pPrivilege, $pUser);
    }

    public function getPermissions(){
	return $this->gateway->getPermissions($this);
    }

    public function setPermissions(array $pRolePermissions, array $pUserPermissions){
	return $this->gateway->setPermissions($this, $pRolePermissions, $pUserPermissions);
    }

    public function render($pAction=null, array $pVars=array()){
	return $this->gateway->render($this, $pAction, $pVars);
    }

    public function __toString(){
	return $this->render('view');
    }

    public function __call($pMethod, $pArgs){

	if (preg_match('/^get(.*)/', $pMethod, $matches)){   //call magic methods on ModuleType

	    $var = '_' . from_camel_case($matches[1]);

	    if (property_exists($this, $var))
		return parent::__call($pMethod, $pArgs);

	}

	$ModuleType = $this->getModuleType();

	Silk::debug("Object.__call: Calling " . $ModuleType->getName() . ".{$pMethod}");

	return $ModuleType->$pMethod($this, $pArgs);
    }
}

 ?>